//
//  ViewController.m
//  JustForTest
//
//  Created by YaoZhaofeng on 16/1/18.
//  Copyright © 2016年 YaoZhaofeng. All rights reserved.
//

#import "ViewController.h"
#import "TestObject.h"
#import "TestObject+CategoryTest.h"
#import "XYMethodTest.h"

static const int kIterationCount = 1000000;

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *myWebView;
@end

@implementation ViewController{
    TestObject *testObject;
}


- (IBAction)clickMe:(id)sender {
   
//    NSString *str2 = [NSString stringWithString:@"1234567890"];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self differenceBetweenSelfWithSuper];
}


/**
 *  self指的是当前方法的调用者，即当前类
 *  super并不是指父类，它是一个编译器的指令符号，告诉编译器在编译的时候调用谁的方法
 *  所以，不管是对self还是super发送消息，消息主体都是self，只是查找方法位置有区别
 */
- (void)differenceBetweenSelfWithSuper{
    NSLog(@"self class is %@",NSStringFromClass([self class]));
    NSLog(@"super class is %@",NSStringFromClass([super class]));
    NSLog(@"self's super class is %@",NSStringFromClass([self superclass]));
}

//结论：autoreleasepool对于alloc init定义的变量是没有用的，下面代码结论异常，猜测是UIbutton内部比较复杂，无法作为参考标准
- (void)memoryTestWithAuto:(BOOL)isAuto{
    __weak UIButton *myBtn;
    for (int i = 0; i < kIterationCount; i++) {
        if (isAuto) {
            @autoreleasepool {
                UIButton *btn = [[UIButton alloc] init];
            }
        }
        else{
            UIButton *btn = [[UIButton alloc] init];
            btn.tag = i;
        }
    }
    NSLog(@"myBtn is %@",myBtn);
}

- (void)testUIWebView{
    [_myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
}


- (void)testCategory{
    
    testObject = [[TestObject alloc] init];
    testObject.categoryProperty = @"just for test";
    
    NSLog(@"testObject.categoryProperty is %@",testObject.categoryProperty);
}

- (void)function:(int)i{
    int j = 100;
    while (j > 0) {
        j--;
    }
}

- (void)testDynamicMethod{
    XYMethodTest *test = [[XYMethodTest alloc] init];
    [test performSelector:@selector(myDynamicMethod)];
}

- (void)testNormalUnrecognizedMethod{
    XYMethodTest *test = [[XYMethodTest alloc] init];
    [test performSelector:@selector(unrecognizedMethod:)];
}

/**
 *  测试发送消息和直接根据方法地址并调用方法的效率
 *结论：直接根据方法地址调用方法比发送消息效率要高
 */
- (void)testFunctionInvoke{
    NSTimeInterval interval1 = [[NSDate date] timeIntervalSince1970];
    NSLog(@"start::%f",interval1);
    for (int i = 0; i< 1000; i++) {
        [self function:i];
    }
    NSTimeInterval interval2 = [[NSDate date] timeIntervalSince1970];
    NSLog(@"end::%f",interval2);
    NSLog(@"cost::%f",interval2-interval1);
    
    void(*function)(id,SEL,int);
    function = (void(*)(id,SEL,int))[self methodForSelector:@selector(function:)];
    
    NSTimeInterval interval3 = [[NSDate date] timeIntervalSince1970];
    NSLog(@"start::%f",interval3);
    for (int i = 0; i< 1000; i++) {
        function(self,@selector(function:),i);
    }
    NSTimeInterval interval4 = [[NSDate date] timeIntervalSince1970];
    NSLog(@"end::%f",interval4);
    NSLog(@"cost::%f",interval4-interval3);
}

/**
 *  测试NSNull的分类功能
 */
- (void)testNSNull{
    NSString *nullObject = [NSNull null];
    
    NSUInteger length = [nullObject length];
    NSLog(@"length is %lu",(unsigned long)length);
    NSLog(@"function::%@",NSStringFromSelector(_cmd));
}

/**
 *  结论：makeObjectsPerformSelector和遍历数组对每个对象执行方法效果一样，在同一个线程按顺序执行
 */
- (void)testSystemApi{
    NSMutableArray *array = [NSMutableArray array];
    for (int i = 0; i<100; i++) {
        TestObject *object = [[TestObject alloc] initWithId:@(i)];
        [array addObject:object];
    }
    [array makeObjectsPerformSelector:@selector(doSomething)];
}

/**
 *  结论：在不同线程中往字典添加和删除元素，只要key不同，不会crash
 */
- (void)testMutDictionaryInMutThread{
    NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];
    
    for (int i = 0; i<100; i++) {
        [tempDic setObject:@(i) forKey:[NSString stringWithFormat:@"%d",i]];
    }
    
    __block int i = 100;
    dispatch_queue_t queue1 = dispatch_queue_create("1111", NULL);
    dispatch_async(queue1, ^{
        while (true) {
            NSLog(@"set value for key:: %i",i);
            [tempDic setObject:@(i) forKey:[NSString stringWithFormat:@"%d",i]];
            i++;
        }
    });
    
    dispatch_queue_t queue2 = dispatch_queue_create("2222", NULL);
    __block int j = 0;
    dispatch_async(queue2, ^{
        while (true) {
            NSLog(@"remove value for key:: %i",j);
            [tempDic removeObjectForKey:[NSString stringWithFormat:@"%d",j]];
            j++;
        }
    });
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
